package cn.cosmosx.base.dict;

import cn.cosmosx.base.exception.PlatformException;
import cn.cosmosx.base.util.ObjectsUtil;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * api字典基类
 */
public interface ApiDict<K, V> {
    /**
     * 字典编码
     */
    K getCode();

    /**
     * 字典描述
     */
    V getDesc();

    /**
     * 字典编码转字典
     *
     * @param code     - 枚举值
     * @param dictType - 字典
     * @return - 枚举实例
     */
    static <T extends Enum<T> & ApiDict<?, ?>> T convert(String code, Class<T> dictType) {
        Assert.isTrue(ObjectsUtil.isNotNull(code), "无效的枚举字典值");
        Assert.notNull(dictType, "没有指定的枚举字典");
        Optional<T> t = Stream.of(dictType.getEnumConstants()).filter(e -> code.equals(e.getCode())).findFirst();
        if (t.isPresent()) {
            return t.get();
        }
        // 如果对应的code没找到，则匹配定义枚举的类型名称name
        t = Stream.of(dictType.getEnumConstants()).filter(e -> code.equals(e.name())).findAny();
        return t.orElseThrow(() -> new PlatformException(String.format("无效的枚举值[%s]", code)));
    }

    default String serialize() {
        return String.valueOf(this.getCode());
    }

    @SuppressWarnings({"all"})
    default ApiDict<K, V> deserialize(String value) {
        if (Objects.isNull(value)) {
            return null;
        }
        ApiDict<?, ?> dict = Arrays.stream(getClass().getEnumConstants())
                .filter(e -> Objects.equals(value, e.getCode())).findFirst()
                .orElseThrow(() -> new IllegalArgumentException("[" + value + "]值未在[" + getClass().getName() + "中定义]"));
        return (ApiDict<K, V>) dict;
    }
}
